<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/7/24
 * Time: 16:38
 */

namespace App\Enum;

/**
 * Class ZjhEnum
 * 炸金花牌值A与牛牛牌值A不同，A为14点
 * @package App\Enum
 */
class ZjhEnum
{
    /**
     * 状态值，游戏步骤 结算完成
     * @var int
     */
    const GAME_STEP_0 = 0;  //默认匹配
    const GAME_STEP_1 = 1;  //发牌
    const GAME_STEP_2 = 2;  //下注
    const GAME_STEP_3 = 3;  //结算完成

    const GAME_STEP = [
        0 => '默认匹配',
        1 => '发牌',
        2 => '下注',
        3 => '结算完成'
    ];

    /**
     * 炸金花牌型
     */
    const GAME_0X26 = 6;	// 豹子
    const GAME_0X25 = 5;	// 同花顺
    const GAME_0X24 = 4;	// 金花
    const GAME_0X23 = 3;	// 顺子
    const GAME_0X22 = 2;	// 对子
    const GAME_0X21 = 1;	// 高牌
    const GAME_0X20 = 0;	// 特殊

    const GAME_ZJH_LEVEL = [
        6=>'豹子',
        5=>'同花顺',
        4=>'金花',
        3=>'顺子',
        2=>'对子',
        1=>'高牌',
        0=>'特殊'//比牌时如果同时存在不同花色(散牌)的352和AAA，352比AAA大
    ];
    /**
     * 回合操作类型
     */
    const HANDLE_TYPE_0 = 0;  //弃牌
    const HANDLE_TYPE_1 = 1;  //比牌
    const HANDLE_TYPE_2 = 2;  //跟注
    const HANDLE_TYPE_3 = 3;  //加注
    const HANDLE_TYPE_4 = 4;  //ALL IN

    const GAME_HANDLE_TYPE = [
        0 => '弃牌',
        1 => '比牌',
        2 => '跟注',
        3 => '加注',
        4 => '孤注一掷'
    ];
    //不考虑花色时
    const GAOPAI_MAX_VAL = 3803;//高牌最大值AKJ = 14*16*16+13*16+11 = 3803
    const DUIZI_MAX_VAL = 4040;//对牌最大值AAk = 14*16+13,加上普通牌最大值3803 = 4040
    const SHUNZI_MAX_VAL = 4052;//顺子最大值AKQ=12,加上对子的最大值4040 = 4052
    const JINHUA_MAX_VAL = 7855;//最大值AKJ，14*16*16+13*16+11=3803，加上顺子4052=7855
    const TONGHUASHUN_MAX_VAL = 7867;//最大值AKQ=12，加上同花7855=7867
    const BAOZI_MAX_VAL = 7881;// 最大值AAA=14，加上同花顺6867=7881

    /**
     * 生成牌规则
     * 游戏一、 抢庄牛牛
    ?  如：值为 360c2c1418 0000000000 360c2c1418 0000000000 1
    ? 字段规则第一位是花色，第二位数是牌值，第三位是花色，第四位数是牌值，以此类推
    ? 每个玩家 5 张手牌共占 10 位，依次为 1-4 号座位的玩家
    ? 最后面一位表示庄家的座位号,1-4 分别对应 1-4 号位
    ? 字符与花色对应关系、字符与牌值对应关系同德州扑克
    ? 例： 值为：360c2c14180000000000360c2c141800000000001 表示：1 号位玩家手牌♠6♦Q♥ Q♣4♣8；2 号位没有玩家；3 号位玩家手牌♠6♦Q♥Q♣4♣8；4 号位没有玩家；庄家是 1号位的玩家
     */

    public static function createRoomGameZJH($playerNum,$param = FALSE,$sigle = false) {
        $everyCard = $param['everyCard'] ?? 3; //每人3张牌
        if(!$playerNum || !$everyCard || intval($everyCard) > 10 ) return false ;
        $fullCards = CardEnum::getFullCards(false); //牌的数据；
        //echo json_encode($fullCards);exit ;
        $fullCards = !empty($fullCards) ? array_column($fullCards, null,'key') : false ;
        $allCards = !empty($fullCards) ? array_column($fullCards,'key') : false ; //所有牌值；
        @shuffle($allCards);    //洗牌；
        $useCards = $lastUserCards =  [];
        $useCardsName = [];
        $valIndex = 0 ;                      //每个玩家取3张牌；
        foreach ($allCards as $r => $paval){ //牌值；
            $thisYl = $valIndex % $playerNum;
            $pinfo = isset($fullCards[$paval])? $fullCards[$paval] :false ;
            if (isset($pinfo) && !empty($pinfo)) {
                //把玩家对应位置的牌值加上去；
                $oneUscard = isset($useCards[$thisYl]) ? $useCards[$thisYl] : [];
                if(empty($oneUscard) || (!empty($oneUscard) && sizeof($oneUscard) < $everyCard)){
                    $useCards[$thisYl][] = $paval;  //把玩家位置的值带上；
                    $useCardsName[$thisYl][] = isset($pinfo["name"]) ? $pinfo["name"] : "";     //牌值；
                }
                $valIndex ++;
            }
        }
        if(!$useCards) return false ;   //牌的数据；
        foreach ($useCards as $pr => $pkey) {
            $pailist = [];
            $paiarr = isset($useCardsName[$pr]) ? $useCardsName[$pr]: false ;
            if(isset($pkey) && !empty($pkey) && !empty($paiarr)){
                $sort1 = [];//按牌值和花色排序
                $sort2 = [];
                foreach ($pkey as $r => $val){  //配置数据
                    $huaval = CardEnum::getCardHua($val);   //花色
                    $dottval = $dott_text = CardEnum::getCardDott($val);  //计算单个值的点数
                    if(isset($val) && $huaval != 4 && $dottval ==1){  $dottval = 14 ;  }//A点数最大和牛牛不一样,顺子时可以做1或者14.
                    $pailist[] = ['key'=>$val,"name"=> isset($paiarr[$r]) ? $paiarr[$r]: "", "dott" => $dottval,"t_dot" =>$dott_text];
                    $sort1[] = $dottval;
                    $sort2[] = $val;
                }
                //相同点数key值大花色也大
                @array_multisort($sort1,SORT_DESC,$sort2,SORT_DESC,$pailist);
                //如果是A32
                if($pailist[0]['dott']==14 && $pailist[1]['dott']==3 && $paiarr[2]['dott']==2){
                    $temp = array_shift($pailist);
                    array_push($pailist,$temp);
                }
                //有对牌和一张单排的先排对牌,且单牌点数比对牌的点数大
                if ($pailist[1]['dott'] == $pailist[2]['dott'] && $pailist[0]['dott'] > $pailist[1]['dott']){
                    $temp = array_shift($pailist);
                    array_push($pailist,$temp);
                }
                //$valIndex = $pr + 1;            //取位置内容；
                $lastUserCards[$pr] = ($sigle==true) ? array_column($pailist,'key') : $pailist;
            }
        }
        return $lastUserCards;
    }

    /**
     * @param array $cards 必须是按照牌值和花色排序好的三张牌的key值，如果是对子,对子放前面,因为之前已做排序,这里不做第二次排序
     * @return bool|int
     */
    public static function getCardsWeight($cards,&$level)
    {
        if(empty($cards) || sizeof($cards)!=3) return false;
        foreach ($cards as $c) {
            $d = CardEnum::getCardDott($c);
            $h = CardEnum::getCardHua($c);
            $dott[] = $d==1 ? 14 : $d;
            $hua[] = $h;
        }
        $d0 = $dott[0];
        $d1 = $dott[1];
        $d2 = $dott[2];
        $h0 = $hua[0];
        $h1 = $hua[1];
        $h2 = $hua[2];
        //花色0,1,2,3花色最大是全是黑桃333,4*4*3+4*3+3=63;
        $hWeight = $h0*16+$h1*4+$h2;
        //豹子
        if ($d0 == $d1 && $d1 == $d2){
            $level =  self::GAME_0X26;
            $dWeight = self::TONGHUASHUN_MAX_VAL+$d0;//最大的同花顺+牌值
            $weight = $dWeight*64+$hWeight;
            return $weight;
        }
        //顺子和32A
        if ($d0 == $d1+1 && $d1 == $d2+1 || [$d0,$d1,$d2] == [3,2,14]){
            //同花顺
            $d2 = $d2==14 ? 1 : $d2;
            if ($h0 == $h1 && $h1 == $h2){
                $level = self::GAME_0X25;
                $dWeight = self::JINHUA_MAX_VAL+$d2;//最大的金花+最小的牌值
                $weight = $dWeight*64+$hWeight;
                return $weight;
            }
            //不同花
            $dWeight = self::SHUNZI_MAX_VAL+$d2;
            $weight = $dWeight*64+$hWeight;
            $level = self::GAME_0X23;
            return $weight;
        }
        //金花
        if ($h0 == $h1 && $h1 == $h2){
            $level = self::GAME_0X24;
            $dWeight = $d0*16*16+$d1*16+$d2 + self::DUIZI_MAX_VAL;
            $weight = $dWeight*64+$hWeight;
            return $weight;
        }
        //对子
        if ($d0 == $d1){
            $level = self::GAME_0X22;
            $dWeight = self::GAOPAI_MAX_VAL+$d0*16+$d2;
            $weight = $dWeight*64+$hWeight;
            return $weight;
        }
        //高牌,特殊牌型只在比较时有豹子的情况下标识;
        $level = self::GAME_0X21;
        $dWeight = $d0*16*16+$d1*16+$d2;
        $weight = $dWeight*64+$hWeight;
        return $weight;
    }

    public static function isSpecial($cards)
    {
        if(empty($cards) || sizeof($cards)!=3) return false;
        foreach ($cards as $c) {
            $d = CardEnum::getCardDott($c);
            $h = CardEnum::getCardHua($c);
            $dott[] = $d==1 ? 14 : $d;
            $hua[] = $h;
        }
        rsort($dott);
        if ($dott==[5,3,2] && sizeof(array_unique($hua))>1){
            return true;
        }
        return false;
    }
    /**
     * $player['cards'],$player['cardsLevel'],$player['cardsWeight']
     * @param $player
     * @param $otherPlayer
     * @param $payPlayer 补偿玩家,当玩家牌型中有包含豹子时返回豹子玩家获得喜钱
     * @return array 返回比牌失败的玩家
     */
    public static function gatherWhoWin($player,$otherPlayer,&$payPlayer = false){
        //豹子和特殊牌同时存在
        $failPlayer = $player;
        if (self::isSpecial($player['cards']) && $otherPlayer['cardsLevel']==self::GAME_0X26){
            $payPlayer = $player;
            $failPlayer = $otherPlayer;
        }elseif($player['cardsLevel']==self::GAME_0X26 && self::isSpecial($otherPlayer['cards'])){
            $payPlayer = $otherPlayer;
        }else{
            //豹子和特殊牌型不同时存在
            if($player['cardsWeight'] > $otherPlayer['cardsWeight']){
                $failPlayer = $otherPlayer;
            }else if($player['cardsWeight'] < $otherPlayer['cardsWeight']){
                $failPlayer =  $player;
            }
        }
        return $failPlayer;

    }
}